﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OWLServer.owl.tipos;
using System.Xml.Linq;
using OWLServer.owl.etiquetas;
using OWLServer.persistencia.interfaces;
using OWLServer.persistencia.ado;

namespace OWLServer.owl.utilidades
{
    /// <summary>
    /// Clase que contiene métodos para manejar las ontologías.
    /// </summary>
    class UtilidadesOntologias
    {
        /// <summary>
        /// Maneja las ontologias de la base de datos
        /// </summary>
        private static IfzOntologiaADO ontologiaADO = new OntologiaADO();

        /// <summary>
        /// Lista de ontologías que tiene el sistema
        /// </summary>
        private static IList<Ontologia> listaOnlologias;

        /// <summary>
        /// Extrae la ontología del OWL
        /// </summary>
        /// <param name="root">Raiz del documento OWL</param>
        /// <returns>Ontolgía del OWL</returns>
        public static Ontologia construirOntologia(IList<EspacioNombres> espaciosNombres, XElement root)
        {
            Ontologia ontologia = null;
            IEnumerable<XElement> eleOntologia;
            String id;
            IDictionary<string, EspacioNombres> espacios = espaciosNombres.ToDictionary(e => e.Nombre, e => e);

            if (UtilidadesEspaciosNombres.contieneOWL(espacios) && UtilidadesEspaciosNombres.contieneRDF(espacios))
            {
                // Extraemos los elementos de la ontologia
                eleOntologia =
                    from el in root.Elements(UtilidadesEspaciosNombres.getEspacioNombres(espacios[EtiquetasOWL.NOMBRE]) + EtiquetasOWL.ONTOLOGIA)
                    select el;

                // Obtenemos el id y creamos la ontologia
                if (eleOntologia.Count() == 1)
                {
                    id = UtilidadesElementos.getId(eleOntologia.ElementAt(0), espacios);
                    ontologia = new Ontologia(id);
                    // Le asignamos el espacio de nombres
                    ontologia.EspacioNombresPrincipal = espacios[String.Empty];
                    ontologia.EspaciosNombres = espaciosNombres;
                }
            }

            return ontologia;
        }

        /// <summary>
        /// Indica si existe o no la ontología en el sistema
        /// </summary>
        /// <param name="ontologia">Ontología a comparar</param>
        /// <returns>Si existe nos la devuelve</returns>
        public static Ontologia existeOntologia(Ontologia ontologia)
        {
            return ontologiaADO.getOntologiaPorEspacioNombrePrincipal(ontologia.EspacioNombresPrincipal, false);
        }

        /// <summary>
        /// Obtienen la lista de ontologías que tiene el sistema
        /// </summary>
        /// <param name="completa">indica si traemos los objetos completamente formados</param>
        /// <returns>Devuelve la lista de ontolologias</returns>
        public static IList<Ontologia> listaOntologias(bool completa)
        {
            listaOnlologias = ontologiaADO.getListOntologias(completa);
            
            return listaOnlologias;
        }

        /// <summary>
        /// Almacena una ontología en la base de datos
        /// </summary>
        /// <param name="ontologia">Ontologia que vamos a almacenar en la BBDD</param>
        public static void almacenarOntologia(Ontologia ontologia)
        {
            ontologiaADO.agregar(ontologia);
        }

        /// <summary>
        /// Elimina una ontología de la base de datos
        /// </summary>
        /// <param name="ontologia">Ontologia que vamos a eliminar de la BBDD</param>
        public static void eliminarOntologia(Ontologia ontologia)
        {
            ontologiaADO.eliminar(ontologia);
        }

        /// <summary>
        /// Actualiza una ontología de la base de datos
        /// </summary>
        /// <param name="ontologia">Ontologia que vamos a actualizar de la BBDD</param>
        public static void actualizarOntologia(Ontologia ontologia)
        {
            ontologiaADO.actualizar(ontologia);
        }

        /// <summary>
        /// Elimina todas las ontologias de la base de datos
        /// </summary>
        public static void limpiarOntologias()
        {
            listaOnlologias = new List<Ontologia>();
            ontologiaADO.limpiar();
        }

        /// <summary>
        /// Recupera una ontologia completa de la base de datos
        /// </summary>
        /// <param name="ontologia">Ontología a recuperar</param>
        /// <returns>Si existe nos la devuelve</returns>
        public static Ontologia recuperarOntologiaCompleta(Ontologia ontologia)
        {
            return ontologiaADO.getOntologiaPorEspacioNombrePrincipal(ontologia.EspacioNombresPrincipal, true);
        }

        /// <summary>
        /// Obtiene una ontología a partir de si Identificador
        /// </summary>
        /// <param name="espacioNombrePrincipal">Identificador de espacio Nombre Principal de la ontología</param>
        /// <param name="completa">Indica si se recuperán todos los datos de la ontología de la base de datos.</param>
        /// <returns>Ontología recuperada</returns>
        public static Ontologia getOntologiaEspacioNombrePrincipal(string espacioNombrePrincipal, bool completa)
        {
            return ontologiaADO.getOntologiaEspacioNombrePrincipal(espacioNombrePrincipal, completa);
        }
    }
}
